package com.yst.sqlbuilder;

import com.yst.lambda.TableFieldFunc;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;
import java.util.Objects;

public class SQLSelectAggField<T> extends SQLAggField<T> implements IAliasExpression,ISelectFieldExpression<T> {
    public SQLSelectAggField<T> setTableAlias(IAliasExpression tableAlias){
        super.setTableAlias(tableAlias);
        return this;
    }
    public SQLSelectAggField(TableFieldFunc<T, ?> field, EnumAggregation aggregation) {
        super(field, aggregation);
    }
    @Override
    public String generateExpression(GenerateParam param) {
        return super.generateExpression(param).concat(" AS ").concat(getAlias());
    }
    public static <T> SQLSelectAggField<T> count(TableFieldFunc<T,?> field){
        return new SQLSelectAggField<>(field,EnumAggregation.COUNT);
    }
    public static <T> SQLSelectAggField<T> max(TableFieldFunc<T,?> field){
        return new SQLSelectAggField<>(field,EnumAggregation.MAX);
    }
    public static <T> SQLSelectAggField<T> sum(TableFieldFunc<T,?> field){
        return new SQLSelectAggField<>(field,EnumAggregation.SUM);
    }
    public static <T> SQLSelectAggField<T> min(TableFieldFunc<T,?> field){
        return new SQLSelectAggField<>(field,EnumAggregation.MIN);
    }
    public static <T> SQLSelectAggField<T> avg(TableFieldFunc<T,?> field){
        return new SQLSelectAggField<>(field,EnumAggregation.AVG);
    }

    static class IFNullAggField<T> extends SQLSelectAggField<T>{
        private final Object value;
        public IFNullAggField(TableFieldFunc<T, ?> field,Object defaultValue) {
            super(field, EnumAggregation.OTHER);
            this.value=defaultValue;
        }
        @Override
        public String generateExpression(GenerateParam param) {
            SQLField<T> sqlField=new SQLField<>(getField(),getTableAlias());
            String result="";
            if (value instanceof Number||value instanceof Boolean) {
                result=result.concat("IFNULL").concat("(").concat(sqlField.generateExpression(param))
                        .concat(",").concat(value.toString()).concat(")");
            }
            else {
                SQLSafe.getInstance().checkValue(value.toString());
                result=result.concat("IFNULL").concat("(").concat(sqlField.generateExpression(param))
                        .concat(",'").concat(value.toString()).concat("')");
            }
            if (!StringUtils.isEmpty(result)&&StringUtils.isNotEmpty(getAlias())){
                result= result.concat(" AS ").concat(getAlias());
            }
            return result;
        }
    }
    public static <T> SQLSelectAggField<T> ifnull(TableFieldFunc<T,?> field, Object defaultValue){
        return new IFNullAggField<>(field,defaultValue);
    }

    private String alias;
    public SQLSelectAggField<T> as(String alias){
        this.alias=alias;
        return this;
    }
    @Override
    public String getAlias() {
        if (Objects.nonNull(alias)) {
            return alias;
        }
        return getRealField();
    }
}
